﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using Portal.Api.FeedProvider;

namespace Portal.FileSystemData
{
  /// <summary>
  /// Represents a file with extended properties.
  /// </summary>
  public class FileWrapper : FileSystemWrapper
  {

    /// <summary>
    /// Zusätzliche Dateiinformation.
    /// </summary>
    protected DirectoryData.FileConfigRow _fileInfoCfg;

    /// <summary>
    /// Constructor.
    /// </summary>
    /// <param name="path">The physical path to the file</param>
    /// <param name="parent">The directory containing this file</param>
    public FileWrapper(string path, DirectoryWrapper parent, DirectoryData.FileConfigRow fileInfoCfg)
      : base(new FileInfo(path), parent)
    {
      _fileInfoCfg = fileInfoCfg;

      if (parent == null)
        throw new ArgumentNullException("parent");
    }


    /// <summary>
    /// The relative virtual path to this item.
    /// </summary>
    [RssElement(ItemElementType.title)]
    public override string VirtualPath
    {
      get { return base.VirtualPath; }
    }

    /// <summary>
    /// The Physical Name of the entry.
    /// </summary>
    public override string Name
    {
      get
      {
        return base.Name;
      }
      set
      {
        base.Name = value;
        if (_fileInfoCfg != null)
        {
          _fileInfoCfg.Name = value;
          SaveData();
        }
      }
    }

    /// <summary>
    /// The filesize.
    /// </summary>
    public long FileSize
    {
      get { return ((FileInfo) _fileSystemInfo).Length; }
    }


    /// <summary>
    /// The mime type.
    /// </summary>
    public String MimeType
    {
      get
      {
        // This section shoud be extracted in a configuration file...
        String mimeType = null;
        if (0 == String.Compare(Extension, "pdf", true))
          mimeType = "application/pdf";
        else if (0 == String.Compare(Extension, "txt", true))
          mimeType = "text/plain";
        else if ((0 == String.Compare(Extension, "doc", true)) || (0 == String.Compare(Extension, "dot", true)))
          mimeType = "application/msword";
        else if (0 == String.Compare(Extension, "xls", true))
          mimeType = "application/vnd.ms-excel";
        else if ((0 == String.Compare(Extension, "ppt", true)) || (0 == String.Compare(Extension, "pps", true)))
          mimeType = "application/mspowerpoint";
        else if (0 == String.Compare(Extension, "gif", true))
          mimeType = "image/gif";
        else if ((0 == String.Compare(Extension, "jpg", true)) || (0 == String.Compare(Extension, "jpeg", true)))
          mimeType = "image/jpeg";
        else if ((0 == String.Compare(Extension, "mpg", true)) || (0 == String.Compare(Extension, "mpeg", true)))
          mimeType = "video/mpeg";
        else if (0 == String.Compare(Extension, "mov", true))
          mimeType = "video/quicktime";
        else if (0 == String.Compare(Extension, "rtf", true))
          mimeType = "application/rtf";
        else if (0 == String.Compare(Extension, "zip", true))
          mimeType = "application/zip";
        else if (0 == String.Compare(Extension, "mp3", true))
          mimeType = "audio/mpeg";
        else
          mimeType = "application/octet-stream";  // Unspezifizierter Mime Type.

        return mimeType;
      }
    }

    /// <summary>
    /// The file extension.
    /// </summary>
    public String Extension
    {
      get
      {
        string extension = ((FileInfo)_fileSystemInfo).Extension;
        if (!string.IsNullOrEmpty(extension))
          extension = extension.Substring(1);

        return extension;
      }
    }

    /// <summary>
    /// Renames the item.
    /// </summary>
    /// <param name="newName">The new name</param>
    protected override void RenameTo(string newName)
    {
      string newPath = Path.Combine(Parent.PhysicalPath, newName);
      ((FileInfo)_fileSystemInfo).MoveTo(newPath);
    }

    /// <summary>
    /// Checks if a filename is allowed.
    /// </summary>
    /// <param name="fileName"></param>
    /// <returns></returns>
    public static bool IsFileNameAllowed(string fileName)
    {
      // Alle Dateinamen die nicht mit "_" beginnen und syntaktisch korrekt sind, sind gültig.
      return !fileName.StartsWith("_") && Portal.Api.Helper.CheckValidFileName(fileName);
    }

    /// <summary>
    /// The caption for displaying in user interfaces.
    /// </summary>
    public override string PresentationName
    {
      get
      {
        return _fileInfoCfg.PresentationName;
      }
      set
      {
        _fileInfoCfg.PresentationName = value;
        SaveData();
      }
    }

    /// <summary>
    /// The string to use as tooltip for the item.
    /// </summary>
    public override string Tooltip
    {
      get
      {
        return _fileInfoCfg.Tooltip;
      }
      set
      {
        _fileInfoCfg.Tooltip = value;
        SaveData();
      }
    }

    /// <summary>
    /// The modification date of the file.
    /// </summary>
    [RssElement(ItemElementType.description)]
    public override string Description
    {
      get { return _fileInfoCfg.Description; }
      set
      {
        if (value != _fileInfoCfg.Description)
        {
          _fileInfoCfg.Description = value;
          SaveData();
        }
      }
    }


    /// <summary>
    /// The modification date of the file.
    /// </summary>
    public override DateTime ModificationDate
    {
      get
      {
        if (_fileInfoCfg.IsModificationDateNull())
        {
          _fileInfoCfg.ModificationDate = base.ModificationDate;
        }
        return _fileInfoCfg.ModificationDate;
      }
      set
      {
        if (value != _fileInfoCfg.ModificationDate)
        {
          _fileInfoCfg.ModificationDate = value;
          SaveData();
        }
      }
    }


    /// <summary>
    /// The publicationdate for an RSS Feed.
    /// </summary>
    [RssElement(ItemElementType.pubDate)]
    public string PubDate
    {
      get
      {
        return Portal.Api.Helper.GetRfc822Date(ModificationDate);
      }
    }


    /// <summary>
    /// The Revision Number of the content.
    /// </summary>
    public int Revision
    {
      get
      {
        return _fileInfoCfg.Revision;
      }
      set
      {
        if (value != _fileInfoCfg.Revision)
        {
          _fileInfoCfg.Revision = value;
          SaveData();
        }
      }

    }

    /// <summary>
    /// An unique string for the content.
    /// </summary>
    [RssElement(ItemElementType.guid)]
    public string UniqueId
    {
      get
      {
        return HttpUtility.UrlEncode(VirtualPath) + "#" + Revision;
      }
    }

    /// <summary>
    /// Deletes the file.
    /// </summary>
    public void DeleteFile()
    {
      // Zuerst wird die physikalische Datei gelöscht.
      ((FileInfo) _fileSystemInfo).Delete();
      
      // Löschen der zugehörigen Daten.
      _fileInfoCfg.Delete();
      _parent.SaveData();

      _parent.Detach(this);
    }

    /// <summary>
    /// Saves the xml data.
    /// </summary>
    private void SaveData()
    {
      _parent.SaveData();
    }

    /// <summary>
    /// Is this item a directory?
    /// </summary>
    public override bool IsDirectory
    {
      get { return false; }
    }
  }
}